#include "picture.h"
#define WIN32_LEAN_AND_MEAN             // Exclude rarely-used stuff from Windows headers
// Windows Header Files:
#include <windows.h>
#include "stdafx.h"
#include <fstream>
#include <iostream>

picture::picture()
{
	X = 0;
	Y = 0;
}
picture::picture(unsigned int x, unsigned int y)
{
	X = x;
	Y = y;
	for (unsigned int i(0); i < X*Y; i++)
		image.push_back(new color(0,0,0,0));
}
picture::picture(const char* name)
{
	bool wczytana(readBMP(name));
}
picture::~picture()
{

}
void picture::setX(unsigned int x)
{
	X = x;
}
void picture::setY(unsigned int y)
{
	Y = y;
}
void picture::setDimensions(unsigned int x, unsigned int y)
{
	X = x;
	Y = y;
}
unsigned int picture::getX()
{
	return X;
}
unsigned int picture::getY()
{
	return Y;
}
void picture::setPixel(unsigned int x, unsigned int y, color pixel)
{
	if (image.size()!= 0)
	{
		image.at(x+y*X)->setColor(pixel);
	}
}
color picture::getPixel(unsigned int x, unsigned int y)
{
	if ((x*y)<=image.size())
		return *(image.at(x+y*X));
	else
		return color(0.0f,0.0f,0.0f);
}
void picture::saveBMP(const char* name)
{
	BITMAPINFOHEADER BMIH;

	BMIH.biSize = sizeof(BITMAPINFOHEADER);
	BMIH.biBitCount = 24;
	BMIH.biPlanes = 1;
	BMIH.biCompression = 0L;
	BMIH.biWidth = X;
	BMIH.biHeight = Y;
	BMIH.biSizeImage = ((((BMIH.biWidth * BMIH.biBitCount) + 31) & ~31) >> 3) * BMIH.biHeight; // magia :P

	int K(X%4);
	unsigned char *img = new unsigned char [X*Y*3 + (2+K)*Y];
	int col;
	color temp;
	for(unsigned int y(0); y < Y; y++)
	{
		for(unsigned int x(0); x < X; x++)
		{
			temp = getPixel(x, y);
			col = (int)(temp.r*255)<<16;
			col += (int)(temp.g*255)<<8;
			col += (int)(temp.b*255);
			*(img + (x + ((Y-1)-y)*X)*3 +(K)*((Y-1)-y) +2) = (BYTE) ((col & 0x00FF0000) >> 16); //R
			*(img + (x + ((Y-1)-y)*X)*3 +(K)*((Y-1)-y) +1) = (BYTE) ((col & 0x0000FF00) >> 8); //G
			*(img + (x + ((Y-1)-y)*X)*3 +(K)*((Y-1)-y)) = (BYTE) (col & 0x000000FF); //B
		}
		switch (K)
		{
			case 3: *(img + (X + ((Y-1)-y)*X)*3 +(K)*((Y-1)-y) +2)=0x00;
			case 2:
			case 1: *(img + (X + ((Y-1)-y)*X)*3 +(K)*((Y-1)-y))=0x00;
		}
	}
	
	FILE *pFile = fopen(name, "wb");
	if(pFile == NULL)
	{

	}
	BITMAPFILEHEADER bmfh;	
	int nBitsOffset = sizeof(BITMAPFILEHEADER) + BMIH.biSize; 
	LONG lImageSize = BMIH.biSizeImage;
	LONG lFileSize = nBitsOffset + lImageSize;
	bmfh.bfType = 'B'+('M'<<8);			
	bmfh.bfOffBits = nBitsOffset;		
	bmfh.bfSize = lFileSize;				
	bmfh.bfReserved1 = bmfh.bfReserved2 = 0;
	//Write the bitmap file header
	UINT nWrittenFileHeaderSize = fwrite(&bmfh, 1, sizeof(BITMAPFILEHEADER), pFile);
	//And then the bitmap info header
	UINT nWrittenInfoHeaderSize = fwrite(&BMIH, 1, sizeof(BITMAPINFOHEADER), pFile);
	//Finally, write the image data itself -- the data represents our drawing
	UINT nWrittenDIBDataSize = fwrite(img, 1, lImageSize, pFile);
	delete [] img;
	
	fclose(pFile);		
}
bool picture::readBMP(const char* name)
{
	FILE *pFile = fopen(name, "rb");
	if(pFile == NULL)
		return false;

	BITMAPINFOHEADER BMIH;
	BITMAPFILEHEADER bmfh;
		//Write the bitmap file header
	UINT nReadFileHeaderSize = fread(&bmfh, 1, sizeof(BITMAPFILEHEADER), pFile);
	//And then the bitmap info header
	UINT nReadInfoHeaderSize = fread(&BMIH, 1, sizeof(BITMAPINFOHEADER), pFile);

	if(BMIH.biBitCount == 24 && BMIH.biCompression == 0L)
	{
		X = BMIH.biWidth;
		Y = BMIH.biHeight;
		int K(X%4);
		BYTE *img = new BYTE [X*Y*3 + (2+K)*Y];
		LONG lImageSize = BMIH.biSizeImage;
		//Finally, write the image data itself -- the data represents our drawing
		UINT nReadDIBDataSize = fread(img, 1, lImageSize, pFile);

		for (unsigned int i(0); i < X*Y; i++)
			image.push_back(new color(0,0,0,1));
		color temp;
		for(unsigned int y(0); y < Y; y++)
		{
			for(unsigned int x(0); x < X; x++)
			{
				BYTE dude;
				dude = (BYTE)*(img + (x + ((Y-1)-y)*X)*3 +(K)*((Y-1)-y) +2); //R
				temp.r = (float)dude/255.0f;	
				dude = (BYTE)*(img + (x + ((Y-1)-y)*X)*3 +(K)*((Y-1)-y) +1); //R
				temp.g = (float)dude/255.0f;	
				dude = (BYTE)*(img + (x + ((Y-1)-y)*X)*3 +(K)*((Y-1)-y)); //R
				temp.b = (float)dude/255.0f;
				setPixel(x, y, temp);
			}
		}
		delete [] img;
	}
	else
		return false;
	fclose(pFile);
	return true;
}